import { Callout, Card, Cards, Steps, Tabs } from "nextra/components";
import UniversalTabs from "@/components/UniversalTabs";
import { Snippet } from "@/components/code";
import { snippets } from "@/lib/generated/snippets";

# Procedural Child Task Spawning

Hatchet supports the dynamic creation of child tasks during a parent task's execution. This powerful feature enables:

- **Complex, reusable task hierarchies** - Break down complex tasks into simpler, reusable components
- **Fan-out parallelism** - Scale out to multiple parallel tasks dynamically
- **Dynamic task behavior** - Create loops and conditional branches at runtime
- **Agent-based tasks** - Support AI agents that can create new tasks based on analysis results or loop until a condition is met

## Creating Parent and Child Tasks

To implement child task spawning, you first need to create both parent and child task definitions.

<UniversalTabs items={["Python", "Typescript", "Go"]}>
<Tabs.Tab title="Python">

First, we'll declare a couple of tasks for the parent and child:

<Snippet src={snippets.python.fanout.worker.fanout_parent} />

We also created a step on the parent task that spawns the child tasks. Now, we'll add a couple of steps to the child task:

<Snippet src={snippets.python.fanout.worker.fanout_child} />

And that's it! The fanout parent will run and spawn the child, and then will collect the results from its steps.

</Tabs.Tab>
<Tabs.Tab title="Typescript">

<Snippet
  src={snippets.typescript.simple.workflow_with_child.declaring_a_task}
/>

</Tabs.Tab>
<Tabs.Tab title="Go">

<Snippet src={snippets.go.child_workflows.main.declaring_the_tasks} />

</Tabs.Tab>
</UniversalTabs>

## Running Child Tasks

To spawn and run a child task from a parent task, use the appropriate method for your language:

<UniversalTabs items={["Python", "Typescript", "Go"]}>
<Tabs.Tab title="Python">

<Snippet src={snippets.python.fanout.example_child_spawn.child_spawn} />

</Tabs.Tab>
<Tabs.Tab title="Typescript">

<Snippet
  src={snippets.typescript.child_workflows.workflow.parent_with_single_child}
/>

</Tabs.Tab>
<Tabs.Tab title="Go">

<Snippet src={snippets.go.child_workflows.main.spawning_a_child_workflow} />

</Tabs.Tab>
</UniversalTabs>

## Parallel Child Task Execution

As shown in the examples above, you can spawn multiple child tasks in parallel:

<UniversalTabs items={["Python", "Typescript", "Go"]}>
<Tabs.Tab title="Python">

<Snippet src={snippets.python.fanout.trigger.bulk_run_children} />

</Tabs.Tab>
<Tabs.Tab title="Typescript">

<Snippet
  src={snippets.typescript.child_workflows.workflow.declaring_a_parent}
/>

</Tabs.Tab>
<Tabs.Tab title="Go">

<Snippet src={snippets.go.child_workflows.main.parallel_child_task_execution} />

</Tabs.Tab>
</UniversalTabs>

## Use Cases for Child Workflows

Child workflows are ideal for:

1. **Dynamic fan-out processing** - When the number of parallel tasks is determined at runtime
2. **Reusable workflow components** - Create modular workflows that can be reused across different parent workflows
3. **Resource-intensive operations** - Spread computation across multiple workers
4. **Agent-based systems** - Allow AI agents to spawn new workflows based on their reasoning
5. **Long-running operations** - Break down long operations into smaller, trackable units of work

## Error Handling with Child Workflows

When working with child workflows, it's important to properly handle errors. Here are patterns for different languages:

<UniversalTabs items={["Python", "Typescript", "Go"]}>
<Tabs.Tab title="Python">

<Snippet src={snippets.python.fanout.example_child_spawn.error_handling} />

</Tabs.Tab>
<Tabs.Tab title="Typescript">

<Snippet
  src={snippets.typescript.child_workflows.workflow.parent_with_error_handling}
/>

</Tabs.Tab>
<Tabs.Tab title="Go">

<Snippet src={snippets.go.child_workflows.main.error_handling} />

</Tabs.Tab>
</UniversalTabs>
